package com.party.mobile.biz.order.payOrder;

import com.party.common.constant.Constant;
import com.party.common.utils.BigDecimalUtils;
import com.party.common.utils.DateUtils;
import com.party.core.model.YesNoStatus;
import com.party.core.model.activity.ActStatus;
import com.party.core.model.activity.Activity;
import com.party.core.model.crowdfund.*;
import com.party.core.model.distributor.DistributorRelation;
import com.party.core.model.distributor.DistributorRelationType;
import com.party.core.model.member.Member;
import com.party.core.model.member.MemberAct;
import com.party.core.model.member.MemberGroup;
import com.party.core.model.member.PartnerMember;
import com.party.core.model.message.MessageOutput;
import com.party.core.model.order.OrderForm;
import com.party.core.model.order.OrderStatus;
import com.party.core.model.order.PaymentState;
import com.party.core.model.order.PaymentWay;
import com.party.core.service.activity.IActivityService;
import com.party.core.service.crowdfund.*;
import com.party.core.service.crowdfund.biz.ProjectDetailCountBizService;
import com.party.core.service.member.IMemberActService;
import com.party.core.service.member.IMemberGroupService;
import com.party.core.service.member.IMemberService;
import com.party.core.service.member.IPartnerMemberService;
import com.party.core.service.order.IOrderFormService;
import com.party.mobile.biz.analyze.MemberMerchantDetailBizService;
import com.party.mobile.biz.crowdfund.SupportBizService;
import com.party.mobile.biz.distributor.DistributorBizService;
import com.party.mobile.biz.order.MessageOrderBizService;
import com.party.mobile.web.dto.crowdfund.input.SupportStatisticsInput;
import com.party.synthesis.IProjectMessageService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @ClassName CrowdfundMultiPayOrderService
 * @Description 多场众筹订单回调处理
 * @Author wei.li
 * @Date 2019/4/17
 **/
@Service
@Component("crowdfundMultiPayOrderService")
public class CrowdfundMultiPayOrderService extends IPayOrderService {

    Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private ISupportService supportService;
    @Autowired
    private IProjectService projectService;
    @Autowired
    private ITargetProjectService targetProjectService;
    @Autowired
    private IActivityService activityService;
    @Autowired
    private MessageOrderBizService messageOrderBizService;
    @Autowired
    private IOrderFormService orderFormService;
    @Autowired
    private IMemberActService memberActService;
    @Autowired
    private IEventGradationService eventGradationService;
    @Autowired
    private IProjectGradationService projectGradationService;
    @Autowired
    private IProjectInfoGradationService projectInfoGradationService;
    @Autowired
    private IProjectMessageService projectMessageService;
    @Autowired
    private IMemberService memberService;
    @Autowired
    private MemberMerchantDetailBizService memberMerchantDetailBizService;
    @Autowired
    private IAnalyzeService analyzeService;
    @Autowired
    private ProjectDetailCountBizService projectDetailCountBizService;
    @Autowired
    private IPartnerMemberService partnerMemberService;
    @Autowired
    private DistributorBizService distributorBizService;
    @Autowired
    private SupportBizService supportBizService;
    @Autowired
    private IMemberGroupService memberGroupService;

    @Override
    public Object doMain(OrderForm orderForm) {
        // 修改支持状态
        Support support = supportService.findByOrderId(orderForm.getId());
        support.setPayStatus(YesNoStatus.YES.getCode());
        supportService.update(support);

        Project project = projectService.get(support.getProjectId());
        Integer isSuccess = null == project.getIsSuccess() ? YesNoStatus.NO.getCode() : project.getIsSuccess();
        TargetProject targetProject = targetProjectService.findByProjectId(project.getId());
        Activity activity = activityService.get(targetProject.getTargetId());
        // 更新众筹信息 TODO 支持人数，支持金额
        project = this.setProject(project, orderForm.getPayment());
        // 更新活动信息 TODO 统计数更改
        activity = this.setActivity(orderForm.getPayment(), activity);
        Map<String, Object> map = this.automaticInto(project, activity,orderForm.getPayment());
        // 处理众筹主订单数据
        if (Constant.IS_SUCCESS.equals(project.getIsSuccess()) && !YesNoStatus.YES.getCode().equals(isSuccess)) {
            this.doCrowdfundSuccess(targetProject.getOrderId());
        }
        map.put("isSuccess",isSuccess);
        return map;
    }

    @Override
    public void doAssist(OrderForm orderForm, Object resultObject) {

        Support support = supportService.findByOrderId(orderForm.getId());
        Project project = projectService.get(support.getProjectId());
        TargetProject targetProject = targetProjectService.findByProjectId(project.getId());
        Activity activity = activityService.get(targetProject.getTargetId());

        // 众筹者
        Member crowdfundMember = memberService.get(project.getAuthorId());
        // 支持者
        Member supportMember = memberService.get(support.getFavorerId());
        // 项目发布者
        MemberGroup orgMember = memberGroupService.get(activity.getMember());

        // 支持者消息推送，海报推送
        this.supportMessageSend(project, orderForm, activity, support, supportMember, crowdfundMember, orgMember);
        if (resultObject != null) {
            try {
                long start = System.currentTimeMillis();
                Map<String, Object> map = (Map<String, Object>) resultObject;
                logger.info("map{}",map.size());
                if (map.containsKey("applycOrRowdfundSuccess")) {
                    List<MessageOutput> messageOutputList = (List) map.get("applycOrRowdfundSuccess");
                    logger.info("推送阶段消息数量{}",messageOutputList.size());
                    for (MessageOutput messageOutput : messageOutputList) {
                        if (messageOutput.getOrderId() != null) {
                            //推送阶段众筹成功消息
                            EventGradation gradation = (EventGradation) messageOutput.getGradation();
                            projectMessageService.gradationCrowfundSuccessSend(messageOutput.getOrderId(),
                                    project.getId(), gradation);
                        } else {
                            //推送阶段报名消息
                            logger.info("开始推阶段报名消息----");
                            EventGradation gradation = (EventGradation) messageOutput.getGradation();
                            projectMessageService.gradationApplySend(project.getId(),
                                    project.getAuthorId(), activity.getId(),
                                    DistributorRelationType.CROWDFUND_REPRESENT.getCode(), gradation);
                        }
                    }
                }
                //推送成功海报
                if (map.containsKey("successPosters") && YesNoStatus.NO.getCode().equals(map.get("isSuccess"))) {
                    logger.info("开始推阶段成功海报----");
                    new Thread(() -> {
                        try {
                            long start10 = System.currentTimeMillis();
                            MessageOutput messageOutput = (MessageOutput) map.get("successPosters");
                            messageOrderBizService.raiseSuccessfulPostersSend(project.getId(),
                                    project.getAuthorId(), messageOutput.getMemberId(), crowdfundMember, orgMember, activity);
                            long end10 = System.currentTimeMillis();
                            logger.info("阶段成功海报执行时间++++++：{}(ms)",(end10 - start10));
                        } catch (Exception e) {
                            logger.error("画海报推送用时异常", e);
                        }
                    }).start();
                }
                long end = System.currentTimeMillis();
                logger.info("阶段推送执行时间：{}(ms)",(end - start));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        //更新合作商统计数
        this.updateMerchantDetail(activity, orderForm.getPayment(), project.getIsSuccess());
        // 更新数据分析的最近7天的众筹金额
        this.doSevenDayNum(project.getId());

        // 处理分销的数据
        long start4 = System.currentTimeMillis();
        this.doStatistics(project.getId(), orderForm);
        long end4 = System.currentTimeMillis();
        logger.info("处理分销的数据：{}(ms)",(end4 - start4));

        // 更新支持者、众筹者的个人数据
        this.updatePersonalData(activity.getMember(), support.getFavorerId(), project.getAuthorId());
        // 统计众筹某天的数据
        this.updateProjectDetail(project.getId(), support.getCreateDate());
    }

    /**
     * @param project 众筹信息
     * @return
     * @Author yifeng
     * @Description 更新众筹信息
     * @Date 9:48 2019/4/11
     **/
    private Project setProject(Project project, Float payment) {
        if (null != project.getRefundState() && !YesNoStatus.YES.getCode().equals(project.getRefundState())) {
            project.setRefundState(YesNoStatus.YES.getCode());
        }
        if(null == project.getRealTimeAmount()){
            project.setRealTimeAmount(0.0f);
        }
        logger.info("projectId：{}，订单金额：{}", project.getId(), payment);
        logger.info("projectId：{}，更新前金额：{}", project.getId(), project.getRealTimeAmount());
        float realTimeAmount = BigDecimalUtils.add(project.getRealTimeAmount(), payment);
        realTimeAmount = BigDecimalUtils.round(realTimeAmount, 2);
        logger.info("projectId：{}，更新后金额：{}", project.getId(), realTimeAmount);

        // 实时已筹集金额
        project.setRealTimeAmount(realTimeAmount);
        // 已筹金额是否大于目标金额
        float actualAmount = realTimeAmount > project.getTargetAmount() ? project.getTargetAmount() : realTimeAmount;
        project.setActualAmount(actualAmount);
        logger.info("projectId：{}，更新前支付人数：{}", project.getId(), project.getFavorerNum());
        project.setFavorerNum(project.getFavorerNum() + 1);
        logger.info("projectId：{}，更新后支付人数：{}", project.getId(), project.getFavorerNum());

        //最后支持时间
        project.setLastSupportDate(DateUtils.getTodayDate());
        return project;
    }

    /**
     * @param payment 金额
     * @return
     * @Author yifeng
     * @Description 更新活动信息
     * @Date 9:50 2019/4/11
     **/
    private Activity setActivity(Float payment, Activity activity) {
        //更改项目
        activity.setFavorerNum(activity.getFavorerNum() + 1);
        activity.setOrderNum(activity.getOrderNum() + 1);

        // 累计资金数
        Double totalMoney = BigDecimalUtils.add(activity.getTotalMoney(), payment);
        totalMoney = BigDecimalUtils.round(totalMoney, 2);
        activity.setTotalMoney(totalMoney);
        return activity;
    }

    /**
     * @param mainOrderId 主订单id
     * @return
     * @Author yifeng
     * @Description 更新众筹主订单的相关数据
     * @Date 14:25 2019/4/11
     **/
    public void doCrowdfundSuccess(String mainOrderId) {
        OrderForm mainOrderForm = orderFormService.get(mainOrderId);
        MemberAct mainMemberAct = memberActService.findByOrderId(mainOrderId);
        mainOrderForm.setIsPay(PaymentState.IS_PAY.getCode());
        mainOrderForm.setPaymentWay(PaymentWay.CROWD_FUND_PAY.getCode());
        mainOrderForm.setStatus(OrderStatus.ORDER_STATUS_HAVE_PAID.getCode());
        mainOrderForm.setUpdateDate(new Date());
        orderFormService.update(mainOrderForm);

        if (mainMemberAct != null) {
            mainMemberAct.setCheckStatus(ActStatus.ACT_STATUS_PAID.getCode());
            mainMemberAct.setPayStatus(MemberAct.PAY_STATUS_YES);
            memberActService.update(mainMemberAct);
        }
    }



    /**
    * @Author hzq
    * @Description //阶段众筹  维护project_gradation中的useTime字段
    * @Date 19:14 2019/4/18
    * @param ongoingProjectGradation
    * @param project
    * @param messageOutputList
    * @param type
    * @return
    **/
    public void updateProjectGradation(ProjectGradation ongoingProjectGradation, Project project,
                                       List<MessageOutput> messageOutputList, int type) {

        //根据当前阶段找到上一阶段
        ProjectGradation projectGradationOnA = projectGradationService.
                getTheNextGradation(ongoingProjectGradation);
        long now = DateUtils.getTodayDate().getTime();
        if (projectGradationOnA == null) {
            long createDate = project.getCreateDate().getTime();
            ongoingProjectGradation.setUseTime(now - createDate);
        } else {
            long createDate;
            if("1970-01-01".equals(DateUtils.formatDate(projectGradationOnA.getSuccessTime()))){
               //如果上个阶段没有成功
                EventGradation eventGradation = eventGradationService.get(projectGradationOnA.getEventGradationId());
                createDate = eventGradation.getEndTime().getTime();
            }else {
                createDate = projectGradationOnA.getSuccessTime().getTime();
            }
            long useTime = now - createDate;
            if (useTime <= 0 && type == 1) {
                useTime = 6000;
            }
            ongoingProjectGradation.setUseTime(useTime);

        }
        if (type == 1) {
            //阶段众筹成功
            ongoingProjectGradation.setSuccessTime(new Date());
            //众筹成功推送参数封装
            EventGradation gradation = eventGradationService.get(ongoingProjectGradation.getEventGradationId());
            TargetProject targetProject = targetProjectService.findByProjectId(project.getId());
            MessageOutput messageOutput = new MessageOutput();
            messageOutput.setOrderId(targetProject.getOrderId());
            messageOutput.setGradation(gradation);
            messageOutputList.add(messageOutput);
        }
        projectGradationService.update(ongoingProjectGradation);
    }

    /**
     * @param project   众筹
     * @param orderForm 订单
     * @param activity  活动
     * @param support   支持
     * @return
     * @Author yifeng
     * @Description 支持者消息推送
     * @Date 11:12 2019/4/11
     **/
    public void supportMessageSend(Project project, OrderForm orderForm, Activity activity, Support support,
                                   Member supportMember, Member crowdfundMember, MemberGroup orgMember) {

        // 付款类型：0为普通众筹，1为直接付款众筹',
        if (project.getPayType() == 0) {
            final String activityMemberId = activity.getMember();
            try {
                messageOrderBizService.supportWechatSend(orderForm, project, supportMember, crowdfundMember, orgMember);
            } catch (Exception e) {
                logger.error("支持消息推送异常：projectId-" + project.getId() + "，supportId-" + support.getId(), e);
            }

            // 在微信公众号上给支持者推送支持海报
            final String projectId = project.getId();
            final String orderMemberId = orderForm.getMemberId();
            try {
                logger.info("开始推送支持海报");
                messageOrderBizService.supportersPostersSend(projectId, orderMemberId, activityMemberId, String.valueOf(orderForm.getPayment()),
                        crowdfundMember, orgMember, activity, supportMember);
                logger.info("支持海报推送完成");
            } catch (Exception e) {
                logger.error("推送支持者海报失败", e);
            }
        }

    }

    /**
     * @param activity  项目
     * @param payment   支持金额
     * @param isSuccess 成功状态
     * @return
     * @Author yifeng
     * @Description 更新合作商统计数
     * @Date 17:40 2019/4/11
     **/
    public void updateMerchantDetail(Activity activity, Float payment, Integer isSuccess) {

        if (YesNoStatus.YES.getCode().equals(isSuccess)) {
            try {
                memberMerchantDetailBizService.updateCrowdfundSuccess(activity.getMember(), payment);
            } catch (Exception e) {
                logger.error("实时更新众筹成功后机构统计数异常", e);
            }
        } else {
            try {
                memberMerchantDetailBizService.updateOrderNum(activity.getMember(), payment);
            } catch (Exception e) {
                logger.error("实时更新支持后机构统计数异常", e);
            }
        }

    }

    /**
     * @param projectId 众筹id
     * @return
     * @Author yifeng
     * @Description 更新数据分析的最近7天的众筹金额
     * @Date 11:32 2019/4/11
     **/
    public void doSevenDayNum(String projectId) {

        try {
            Date now = new Date();
            Date startDate = DateUtils.addDay(now, -6);
            // 最近七天的众筹金额 todo 有查询支持者
            Float sevenDaysNum = supportService.countBySupportDate(DateUtils.formatDate(startDate),
                    DateUtils.formatDate(now), projectId);
            Analyze analyze = analyzeService.findByTargetId(projectId);
            if (null != analyze) {
                analyze.setSevenDaysNum(sevenDaysNum);
                analyzeService.update(analyze);
                logger.info("支持者支付成功后更新analyze中的sevenDaysNum字段成功");
            }
        } catch (Exception e) {
            logger.error("支持完成后, 更新analyze数据异常", e);
        }

    }

    /**
     * @param projectId         众筹id
     * @param supportCreateDate 创建时间
     * @return
     * @Author yifeng
     * @Description 统计众筹某天的数据
     * @Date 16:01 2019/4/11
     **/
    public void updateProjectDetail(String projectId, Date supportCreateDate) {
        try {
            projectDetailCountBizService.countProjectSomeDay(projectId, supportCreateDate);
        } catch (Exception e) {
            logger.error("众筹统计分析数据更新异常", e);
        }
    }


    /***
     * 多场活动支付回调 维护zc_project_info,zc_project_gradation
     * @param
     * @param project
     */
    public Map<String, Object> automaticInto(Project project, Activity activity,Float payment) {
        Map<String, Object> map = new HashMap();
        List<MessageOutput> messageOutputList = new ArrayList<>();
        int type = 0;//默认阶段没有成功
        //获取ProjectInfoGradation对象
        ProjectInfoGradation byProjectId = projectInfoGradationService.findByProjectId(project.getId());
        //根据projectId 找到当前众筹者正在众筹哪个阶段
        EventGradation ongoingGradation = eventGradationService.getOngoingGradation(project.getId());
        ProjectGradation ongoingProjectGradation = projectGradationService.
                getByEventGradationId(ongoingGradation.getId(), project.getId());

        //找到当前系统阶段之前所有成功阶段的目标金额之和
        Double effectiveAmount = projectGradationService.getEffectiveAmount(ongoingGradation.getEndTime(), project.getId());
        //累计金额减去前面阶段的众筹成功金额等于剩余金额
        double surplus = BigDecimalUtils.sub(project.getActualAmount().doubleValue(), effectiveAmount);
        surplus = BigDecimalUtils.round(surplus, 2);
        //如果剩余金额大于等于当前系统阶段的目标金额，那说明当前阶段已经成功了
        if (surplus >= ongoingProjectGradation.getTargetAmount()) {
            if (effectiveAmount < 0.01) {
                // 商品正在众筹人数减
                activity.setCrowdfundedNum(activity.getCrowdfundedNum() + 1);
                Integer beCrowdfundNum = activity.getBeCrowdfundNum() - 1 <= 0 ? 0 : activity.getBeCrowdfundNum() - 1;
                activity.setBeCrowdfundNum(beCrowdfundNum);
                activity.setSalesNum(activity.getSalesNum() + 1);
            }
            type = 1;//阶段成功了
            //获取当前系统阶段之后的阶段
            List<ProjectGradation> projectGradationList = projectGradationService.getAfterProjectGradations(ongoingGradation, project.getId());
            //目标金额
            double targetMoney = ongoingProjectGradation.getTargetAmount();

            if (projectGradationList.size() > 0) {
                for (ProjectGradation projectGradation : projectGradationList) {
                    byProjectId.setProjectGradationId(projectGradation.getId());
                    projectInfoGradationService.update(byProjectId);
                    this.updateProjectGradation(ongoingProjectGradation, project, messageOutputList,type);
                    //阶段报名推送参数封装
                    EventGradation gradation = eventGradationService.get(projectGradation.getEventGradationId());
                    MessageOutput messageOutput = new MessageOutput();
                    messageOutput.setGradation(gradation);
                    messageOutputList.add(messageOutput);

                    targetMoney = BigDecimalUtils.add(targetMoney, projectGradation.getTargetAmount());
                    targetMoney = BigDecimalUtils.round(targetMoney, 2);
                    double round = BigDecimalUtils.round(BigDecimalUtils.sub(surplus, targetMoney), 2);
                    if (round < 0) {
                        break;
                    }
                    /** 如果最后一个阶段都筹满了 那update最后一个阶段的project_gradation*/
                    ProjectGradation projectGradation1 = projectGradationList.get(projectGradationList.size() - 1);
                    if (projectGradation.getId().equals(projectGradation1.getId())) {
                        this.updateProjectGradation(projectGradation, project, messageOutputList,type);
                        project.setIsSuccess(Constant.IS_SUCCESS);

                        activity.setSalesNum(activity.getSalesNum() + 1);
                        Float salesAmount = BigDecimalUtils.add(activity.getSalesAmount(), payment);
                        salesAmount = BigDecimalUtils.round(salesAmount, 2);
                        activity.setSalesAmount(salesAmount);
                    }
                    ongoingProjectGradation = projectGradation;
                }
                logger.info("多场活动支付回调更新数据结束11");
            } else {
                /** 说明是最后一场成功了*/
                this.updateProjectGradation(ongoingProjectGradation, project, messageOutputList,type);
                project.setIsSuccess(Constant.IS_SUCCESS);
                activity.setSalesNum(activity.getSalesNum() + 1);
                Float salesAmount = BigDecimalUtils.add(activity.getSalesAmount(), payment);
                salesAmount = BigDecimalUtils.round(salesAmount, 2);
                activity.setSalesAmount(salesAmount);
            }
            map.put("applycOrRowdfundSuccess", messageOutputList);

            if (project.getPayType() == 0) {
                //成功海报推送封装
                MessageOutput messageOutput = new MessageOutput();
                messageOutput.setMemberId(activity.getMember());
                map.put("successPosters", messageOutput);
            }
        } else {
            //阶段未筹满  改ProjectGradation 中的useTime
            this.updateProjectGradation(ongoingProjectGradation, project, messageOutputList,type);
        }

        projectService.update(project);
        activityService.update(activity);
        return map;
    }

    /**
     * @param orgId             机构id
     * @param supportMemberId   支持者id
     * @param crowdfundMemberId 众筹者id
     * @return
     * @Author yifeng
     * @Description 处理个人统计数校正
     * @Date 14:30 2019/4/11
     **/
    public void updatePersonalData(String orgId, String supportMemberId, String crowdfundMemberId) {
//        new Thread(() -> {
        try {
            //机构用户
            PartnerMember partnerMember = new PartnerMember();
            partnerMember.setPartnerId(orgId);
            partnerMember.setMemberId(supportMemberId);
            partnerMemberService.getSet(partnerMember);

//                memberPersonalCountBizService.countOne(partnerMember);
        } catch (Exception e) {
            logger.error("处理支持者的个人统计数校正异常", e);
        }
//            try {
//                PartnerMember projectPartnerMemberCount = partnerMemberService.findByPartnerAndMember(orgId, crowdfundMemberId);
//                memberPersonalCountBizService.countOne(projectPartnerMemberCount);
//            } catch (Exception e) {
//                logger.error("处理众筹者的个人统计数校正异常", e);
//            }
//        }).start();
    }

    /**
     * @param projectId 众筹id
     * @param orderForm 支持订单
     * @return
     * @Author yifeng
     * @Description 处理分销的数据
     * @Date 17:47 2019/4/11
     **/
    public void doStatistics(String projectId, OrderForm orderForm) {
        try {
            DistributorRelation disRelation = distributorBizService.getDistributorRelation(projectId);
            SupportStatisticsInput supportStatisticsInput = new SupportStatisticsInput();
            supportStatisticsInput.setProjectId(projectId);
            supportStatisticsInput.setSupportId(orderForm.getId());
            supportStatisticsInput.setPayment(orderForm.getPayment());
            supportBizService.statistics(supportStatisticsInput, disRelation, false, null);
        } catch (Exception e) {
            logger.error("支持数据统计分销数据异常", e);
        }
    }
}
